extends Spatial

onready var my_camera = $LevelTemplate/MyCamera

onready var rotation_ctl: LineEdit = $GUI/VBoxContainer/GridContainer2/rotation
onready var slope_ctl: LineEdit = $GUI/VBoxContainer/GridContainer2/slope

var current_ball: RigidBody = null

func _ready():
	var gc: GridContainer = $GUI/VBoxContainer/GridContainer

	for p in [
		"gravity",
		"radius", "friction", "bounce",
		"mass", "my_linear_damp", "my_angular_damp",
		"strength",
	]:
		var lbl: Label = Label.new()
		lbl.text = p
		gc.add_child(lbl)
		var txt: LineEdit = LineEdit.new()
		txt.name = p
		txt.size_flags_horizontal = Control.SIZE_EXPAND_FILL
# warning-ignore:return_value_discarded
		txt.connect("mouse_exited", self, "_on_mouse_exited", [txt])
		gc.add_child(txt)

func _on_mouse_exited(obj):
	obj.release_focus()

# warning-ignore:unused_argument
func _process(delta):
	if current_ball != my_camera.followed_object:
		current_ball = my_camera.followed_object
		show_ball_info()

	if current_ball != null:
		show_vec3($GUI/VBoxContainer/GridContainer/position, current_ball.global_transform.origin)
		var v: Vector3 = current_ball.linear_velocity
		show_vec3($GUI/VBoxContainer/GridContainer/velocity, v)
		$GUI/VBoxContainer/GridContainer/speed.text = "%0.3f" % v.length()

func show_vec3(ctl, v):
	var props = ["x", "y", "z"]
	for i in 3:
		ctl.get_node(props[i]).text = "%0.3f" % v[i]

func show_ball_info():
	var gc: GridContainer = $GUI/VBoxContainer/GridContainer

	for p in [
		"ball_type",
		"position/x", "position/y", "position/z",
		"velocity/x", "velocity/y", "velocity/z",
		"gravity",
		"radius", "friction", "bounce",
		"mass", "my_linear_damp", "my_angular_damp",
		"strength",
	]:
		gc.get_node(p).text = ""

	if current_ball == null:
		return

	var pmo: PhysicsMaterial = current_ball.physics_material_override
	if pmo != null:
		for p in ["friction", "bounce"]:
			gc.get_node(p).text = str(pmo.get(p))

	var cs: CollisionShape = current_ball.get_node_or_null("CollisionShape")
	if cs != null and cs.shape is SphereShape:
		gc.get_node("radius").text = str(cs.shape.radius)

	for p in [
		"ball_type",
		"mass", "my_linear_damp", "my_angular_damp",
		"strength",
	]:
		gc.get_node(p).text = str(current_ball.get(p))

	var g: float = current_ball.gravity_scale * ProjectSettings.get("physics/3d/default_gravity")
	gc.get_node("gravity").text = str(g)

func _on_Apply_pressed():
	if current_ball != null:
		var gc: GridContainer = $GUI/VBoxContainer/GridContainer

		var pmo: PhysicsMaterial = PhysicsMaterial.new()
		for p in ["friction", "bounce"]:
			pmo.set(p, gc.get_node(p).text as float)
		current_ball.physics_material_override = pmo

		var cs: CollisionShape = current_ball.get_node_or_null("CollisionShape")
		if cs != null and cs.shape is SphereShape:
			var r: float = gc.get_node("radius").text as float
			if abs(cs.shape.radius - r) > 1e-3:
				current_ball.global_transform.origin += Vector3(0.0, r - cs.shape.radius, 0.0)

				var shape: SphereShape = cs.shape.duplicate()
				shape.radius = r
				cs.shape = shape

				var mi: MeshInstance = current_ball.get_node_or_null("MeshInstance")
				if mi != null and mi.mesh != null and mi.mesh is SphereMesh:
					var mat: Material = mi.get_surface_material(0)
					var mesh: SphereMesh = mi.mesh.duplicate()
					mesh.radius = r
					mesh.height = r * 2.0
					mi.mesh = mesh
					mi.set_surface_material(0, mat)

		for p in [
			"mass", "my_linear_damp", "my_angular_damp",
			"strength",
		]:
			current_ball.set(p, gc.get_node(p).text as float)

		current_ball.gravity_scale = (gc.get_node("gravity").text as float) / ProjectSettings.get("physics/3d/default_gravity")

func _on_ResetPosition_pressed():
	if current_ball != null:
		current_ball.global_transform = Transform()
		current_ball.linear_velocity = Vector3()
		current_ball.angular_velocity = Vector3()


func _on_rotation_mouse_exited():
	if rotation_ctl.has_focus():
		rotation_ctl.release_focus()
		slope_ctl.text = str(tan(deg2rad(clamp( \
			rotation_ctl.text as float, -89.9, 89.9))))

func _on_slope_mouse_exited():
	if slope_ctl.has_focus():
		slope_ctl.release_focus()
		rotation_ctl.text = str(rad2deg(atan(slope_ctl.text as float)))

func _on_Apply2_pressed():
	var b: Basis = Basis(Vector3(-1, 0, 0), Vector3(0, 1, 0), Vector3(0, 0, -1))
	$GeneralFloor2.transform.basis = b.rotated(Vector3(1, 0, 0), deg2rad(clamp( \
		rotation_ctl.text as float, -89.9, 89.9)))
